package cn.qu.phizline.webserver.ws;

import cn.qu.phizline.common.ByteBuffer;
import cn.qu.phizline.event.Payload;
import cn.qu.phizline.webserver.event.WebPayloadConventer;
import cn.qu.phizline.webserver.event.handle.Handle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by zh on 17/8/29.
 */
public class WebServer {
    private static final Logger logger = LoggerFactory.getLogger(WebServer.class);

    private Map<String, Class<? extends Payload>> payloadMap = new ConcurrentHashMap<>();
    private Map<String, Class<? extends Handle>> payloadHandleMap = new ConcurrentHashMap<>();

    public void register(Class<? extends Payload> payloadClazz, Class<? extends Handle> handleClazz) {
        try {
            Payload payload = payloadClazz.newInstance();
            String key = getPayloadKey(payload.getType(), payload.getVersion());

            payloadMap.put(key, payloadClazz);
            payloadHandleMap.put(key, handleClazz);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public Class<? extends Handle> getHandleType(int type, int version) {
        return payloadHandleMap.get(getPayloadKey(type, version));
    }

    public <T extends Payload> T load(byte[] bytes) {
        ByteBuffer buffer = new ByteBuffer(bytes);

        int type = buffer.uint4();
        int version = buffer.uint4();
        int len = buffer.uint8();

        Class<? extends Payload> clazz = payloadMap.get(getPayloadKey(type, version));

        Payload payload = new WebPayloadConventer().fromBytes(clazz, buffer.read(len));
        return (T) payload;
    }

    public static String getPayloadKey(int type, int version) {
        return String.format("%s_%s", type, version);
    }

}
